package com.ruoyi.system.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 微信登录 WebSocket 消息处理
 * 用于扫码登录场景的实时通信
 * 
 * @author flybird
 */
@Component
@ServerEndpoint(value = "/websocket/wxLogin/{id}")
public class WxLoginWebSocketServer {
    
    /**
     * 日志控制器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(WxLoginWebSocketServer.class);
    
    /**
     * 存储所有连接的会话，key为id，value为Session
     */
    private static Map<String, Session> sessions = new ConcurrentHashMap<>();
    
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "id") String id) {
        try {
            // 存储会话
            sessions.put(id, session);
            LOGGER.info("微信登录WebSocket连接建立成功，ID: {}, SessionId: {}", id, session.getId());
            LOGGER.info("当前连接数: {}", sessions.size());
            
            // 发送连接成功消息
            sendMessage(session, "连接成功");
            
        } catch (Exception e) {
            LOGGER.error("WebSocket连接建立失败，ID: {}, 错误: {}", id, e.getMessage());
        }
    }
    
    /**
     * 连接关闭时处理
     */
    @OnClose
    public void onClose(Session session, @PathParam(value = "id") String id) {
        try {
            // 移除会话
            sessions.remove(id);
            LOGGER.info("微信登录WebSocket连接关闭，ID: {}, SessionId: {}", id, session.getId());
            LOGGER.info("当前连接数: {}", sessions.size());
            
        } catch (Exception e) {
            LOGGER.error("WebSocket连接关闭处理失败，ID: {}, 错误: {}", id, e.getMessage());
        }
    }
    
    /**
     * 抛出异常时处理
     */
    @OnError
    public void onError(Session session, Throwable error, @PathParam(value = "id") String id) {
        try {
            LOGGER.error("微信登录WebSocket连接异常，ID: {}, SessionId: {}, 错误: {}", id, session.getId(), error.getMessage());
            
            // 移除会话
            sessions.remove(id);
            
            // 关闭连接
            if (session.isOpen()) {
                session.close();
            }
            
        } catch (Exception e) {
            LOGGER.error("WebSocket异常处理失败，ID: {}, 错误: {}", id, e.getMessage());
        }
    }
    
    /**
     * 服务器接收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam(value = "id") String id) {
        LOGGER.info("收到来自客户端的消息，ID: {}, SessionId: {}, 消息: {}", id, session.getId(), message);
        
        // 简单回复确认消息
        sendMessage(session, "消息已收到: " + message);
    }
    
    /**
     * 向指定ID的客户端发送消息
     * 
     * @param id 客户端ID
     * @param message 消息内容
     * @return 是否发送成功
     */
    public static boolean sendMessageToClient(String id, String message) {
        try {
            Session session = sessions.get(id);
            if (session != null && session.isOpen()) {
                sendMessage(session, message);
                LOGGER.info("向客户端发送消息成功，ID: {}, 消息: {}", id, message);
                return true;
            } else {
                LOGGER.warn("客户端连接不存在或已关闭，ID: {}", id);
                return false;
            }
        } catch (Exception e) {
            LOGGER.error("向客户端发送消息失败，ID: {}, 消息: {}, 错误: {}", id, message, e.getMessage());
            return false;
        }
    }
    
    /**
     * 向指定会话发送消息
     * 
     * @param session 会话
     * @param message 消息内容
     */
    private static void sendMessage(Session session, String message) {
        try {
            if (session.isOpen()) {
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            LOGGER.error("发送消息失败，SessionId: {}, 消息: {}, 错误: {}", session.getId(), message, e.getMessage());
        }
    }
    
    /**
     * 获取当前连接数
     * 
     * @return 连接数
     */
    public static int getConnectionCount() {
        return sessions.size();
    }
    
    /**
     * 检查指定ID的客户端是否在线
     * 
     * @param id 客户端ID
     * @return 是否在线
     */
    public static boolean isClientOnline(String id) {
        Session session = sessions.get(id);
        return session != null && session.isOpen();
    }
    
    /**
     * 广播消息给所有连接的客户端
     * 
     * @param message 消息内容
     */
    public static void broadcastMessage(String message) {
        LOGGER.info("广播消息给所有客户端: {}", message);
        
        sessions.forEach((id, session) -> {
            try {
                if (session.isOpen()) {
                    sendMessage(session, message);
                }
            } catch (Exception e) {
                LOGGER.error("广播消息失败，ID: {}, 错误: {}", id, e.getMessage());
            }
        });
    }
    
    /**
     * 关闭指定ID的连接
     * 
     * @param id 客户端ID
     */
    public static void closeConnection(String id) {
        try {
            Session session = sessions.get(id);
            if (session != null && session.isOpen()) {
                session.close();
                sessions.remove(id);
                LOGGER.info("主动关闭客户端连接，ID: {}", id);
            }
        } catch (Exception e) {
            LOGGER.error("关闭客户端连接失败，ID: {}, 错误: {}", id, e.getMessage());
        }
    }
} 